//
//  EzOnvifServer.hpp
//  ffmpeg_onvif
//
//  Created by 刘跃龙 on 8/9/18.
//  Copyright © 2018 absolutemobile. All rights reserved.
//

#ifndef EzOnvifServer_hpp
#define EzOnvifServer_hpp

#include "EzTools.h"
#include <stdio.h>
#include <string>
//#include "EzMulticastServer.h"
//#include "EzSocketServer.h"

#include "tinyxml.h"
#include <vector>

EZ_BEGIN

class EzOnvifServer
{
public:
//    typedef struct VideoSource_t{
//        std::string token = "VideoSource_token1";
//        int Framerate = 25;
//    }VideoSource;
//    typedef struct VideoEncoderConfiguration_t{
//        std::string token = "H264Video_cfg_token1";
//        std::string Name = "H264Video_cfg1";
//        std::string Encoding = "H264";
//    }VideoEncoderConfiguration;
//    typedef struct AudioEncoderConfiguration_t{
//        std::string token = "AACAudio_cfg_token1";
//        std::string Name = "AACAudio_cfg";
//        std::string Encoding = "AAC";
//        int Bitrate = 16;
//        int SampleRate = 16000;
//    }AudioEncoderConfiguration;
    typedef struct SnapshotUri_t{
        SnapshotUri_t(){
            protocol = "http";
            host = "";
            port = 18080;
            path = "/onvif/snapshot.jpeg";
        }
        std::string protocol;
        std::string host;
        unsigned short int port;
        std::string path;
    }SnapshotUri;
    typedef struct StreamUri_t{
        StreamUri_t(){
            protocol = "rtsp";
            host = "";
            port = 554;
            path = "/live";
        }
        std::string protocol;
        std::string host;
        unsigned short int port;
        std::string path;
    }StreamUri;
    typedef struct Profile_t{
        Profile_t(){
            token = "Profile_token1";
            Name = "Profile1";
        }
        std::string token;
        std::string Name;
        StreamUri streamUri;
        SnapshotUri snapshotUri;
//        VideoSource videoSource;
//        VideoEncoderConfiguration videoEncoderConfiguration;
//        AudioEncoderConfiguration AudioEncoderConfiguration;
    }Profile;
public:
    static EzOnvifServer* instance;
    static EzOnvifServer* getInstance();
private:
    EzOnvifServer(unsigned short int port = 80,std::string uuid = "",std::string path = "/onvif/ezhomelabs",std::string localIP = "");
    ~EzOnvifServer();
public:
    static std::string getHttpHead(int code,long len);
    static std::string getLocalIP();
    static std::string getUUID();
    static std::string getPasswordDigest(std::string password,std::string nonce,std::string created);
public:
    void addProfile(Profile profile){m_profileList.push_back(profile);};
    void clearProfile(){m_profileList.clear();};
    void start();
    void stop();
public:
    std::string onMulticastData(std::string data);
    std::string onSocketData(std::string data);
private:
    std::string getResProbeMatches(std::string messageId,std::string type);
    std::string getResNotAuthorized(TiXmlDocument* pDoc);
    std::string getResInvalidArgVal(TiXmlDocument* pDoc);
    std::string getResFromCMD(TiXmlDocument* pDoc,std::string cmd);
    std::string getResGetDeviceInformation(TiXmlDocument* pDoc);
    std::string getResGetCapabilities(TiXmlDocument* pDoc);
    std::string getResGetSystemDateAndTime(TiXmlDocument* pDoc);
    std::string getResGetServices(TiXmlDocument* pDoc);
    std::string getResGetProfiles(TiXmlDocument* pDoc);
    std::string getResGetProfile(TiXmlDocument* pDoc);
    std::string getResGetStreamUri(TiXmlDocument* pDoc);
    std::string getResGetSnapshotUri(TiXmlDocument* pDoc);
    std::string getResGetVideoSourceConfiguration(TiXmlDocument* pDoc);
    std::string getResGetVideoEncoderConfigurations(TiXmlDocument* pDoc);
    
    
    std::string getResGetVideoSources(TiXmlDocument* pDoc);
private:
    EzOnvifServer::Profile getProfileFromToken(std::string token);
    bool isCheckAuthorized(std::string cmd);
    bool checkUsernameToken(TiXmlElement* usernameToken);
    void addProfile(TiXmlElement* parent,Profile profile,std::string rootValue = "");
    void addVideoSource(TiXmlElement* parent);
    void addVideoEncoderConfiguration(TiXmlElement* parent,std::string rootValue = "");
    void addAudioEncoderConfiguration(TiXmlElement* parent,std::string rootValue = "");
private:
    std::string m_lastBuffer;
    unsigned short int m_port;
    std::string m_uuid;
    std::string m_path;
//    DeviceInfomation m_deviceInfomation;
//    EzMulticastServer* m_multicastServer;
//    EzSocketServer* m_socketServer;
    std::vector<Profile> m_profileList;
};

EZ_END

#endif /* EzOnvifServer_hpp */
